﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Sublimation
{
    public class Bullet : GameObject
    {
        #region Attributes
        protected int chargeTime;
        protected int maxChargeTime = 550;
        protected bool isFriendly;
        public bool IsFriendly
        {
            get { return this.isFriendly; }
            set { this.isFriendly = value; }
        }

        protected float damagePotential;
        public float DamagePotential
        {
            get { return this.damagePotential; }
            set { this.damagePotential = value; }
        }

        protected Vector2 size;
        protected Vector2 initial_position;
        protected float range;

        protected float maxSpeed;
        public float MaxSpeed
        {
            get { return this.maxSpeed; }
            set { this.maxSpeed = value; }
        }

        protected Rectangle area;
        #endregion


        public Bullet(WorldProperties worldProperties, bool isFriendly, Vector2 position,Vector2 velocity, float maxSpeed, Vector2 size,float range,float damagePotential, Vector2 targetPosition)
            : base(worldProperties)
        {
            MaxSpeed = maxSpeed;
            LoadContent();
            
            // make sure it loads and draws
            DrawOrder = 80;
            UpdateOrder = 50;
            Visible = true;
            Enabled = true;

            SetOriginToCentre();
            this.size = size;
            this.isFriendly = isFriendly;

            this.velocity = velocity;
            //this.velocity = targetPosition - position;
            this.velocity.Normalize();
            this.velocity *= MaxSpeed;

            this.Rotation = (float)Math.Atan2(velocity.Y, velocity.X);
            this.position = position +Vector2.Normalize(velocity) * 50; //TODO: make this actually based on location of the weapon's barrel
            this.initial_position = position;
            this.range = range;
            this.damagePotential = damagePotential;
            CollisionRadius = 3;
            Visible = false;
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        public override void DoMovement(GameTime gameTime)
        {
            if (chargeTime == 0)
            {
                chargeTime = (int)gameTime.TotalRealTime.TotalMilliseconds;
            }
            if ((int)gameTime.TotalRealTime.TotalMilliseconds - chargeTime>maxChargeTime)
            {
                Visible = true;
                base.DoMovement(gameTime);
                this.Rotation = (float)Math.Acos(Vector2.Dot(Vector2.UnitX, Velocity) / Velocity.Length()) * Math.Sign(Vector2.Dot(Vector2.UnitY, Velocity));
            }
        }
        public override void CheckCollisions(GameTime gameTime)
        {
            base.CheckCollisions(gameTime);

            //TODO: physical objects

            //limited range
            if (Vector2.Distance(position, initial_position) > range)
            {
                Kill();
            }
            // Towers, only do damage if not friendly bullet
            foreach (Player player in worldProperties.Players)
            {
                foreach (Tower tower in player.Towers)
                {
                    if (CollidesWith(tower))
                    {
                        Kill();
                        if (!IsFriendly) tower.ApplyDamage(DamagePotential);
                        return;
                    }
                }
            }

            // Units
            if (IsFriendly)
            {
                // collide with enemy units
                foreach (EnemyUnit unit in worldProperties.Enemies)
                {
                    if (CollidesWith(unit))
                    {
                        Kill();
                        unit.ApplyDamage(DamagePotential);
                        return;
                    }
                }
            }
            else
            {
               // collide with friendly units
                foreach (Player player in worldProperties.Players)
                {
                    foreach (Unit unit in player.Units)
                    {
                        if (CollidesWith(unit))
                        {
                            Kill();
                            unit.ApplyDamage(DamagePotential);
                            return;
                        }
                    }
                }
            }
        }

        protected override void LoadContent()
        {
            base.LoadContent();
            Sprite = Game.Content.Load<Texture2D>("Sprites/fireball");
            Scale = 1.0f;
        }
    }
}
